package com.moody.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.ServletContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.moody.hibernate.dao.AdjValueDAO;
import com.moody.hibernate.dao.CustAddressDAO;
import com.moody.hibernate.dao.DebtCollateralDAO;
import com.moody.hibernate.dao.DebtInfoDAO;
import com.moody.hibernate.dao.LgdHDAO;
import com.moody.hibernate.dao.ModelInfoDAO;
import com.moody.hibernate.dao.PdHDAO;
import com.moody.hibernate.dao.QuaValueDAO;
import com.moody.hibernate.dao.RatioValueDAO;
import com.moody.hibernate.domain.AdjValue;
import com.moody.hibernate.domain.CustInfo;
import com.moody.hibernate.domain.DebtCollateral;
import com.moody.hibernate.domain.DebtInfo;
import com.moody.hibernate.domain.LgdH;
import com.moody.hibernate.domain.ModelInfo;
import com.moody.hibernate.domain.PdH;
import com.moody.hibernate.domain.QuaValue;
import com.moody.hibernate.domain.QuaValueId;
import com.moody.hibernate.domain.RatioValue;
import com.moody.hibernate.domain.RoleInfo;
import com.moody.init.RoleRightInit;
import com.moody.service.RatingService;
import com.moody.service.SystemService;
/*
 * Copyright © Moody analytics
 *
 * @Author: Wang Fuqiang
 * @Time: 2011-11-9 上午10:58:31
 * @Modified by: 
 * @Description: 
 */
@Service
public class RatingServiceImpl implements RatingService{
	private static final Logger log = LoggerFactory.getLogger(CustomerServiceImpl.class);
	WebApplicationContext web = ContextLoader.getCurrentWebApplicationContext();
	ServletContext context = web.getServletContext();  
	WebApplicationContext ctx  = WebApplicationContextUtils.getWebApplicationContext(context);
	ServletContext servletContext=web.getServletContext();
	Map<String, List<String>> orgMap = (Map<String, List<String>>)servletContext.getAttribute("OrgMap");
	
	private PdHDAO pdhDAO = PdHDAO.getFromApplicationContext(ctx);
	private LgdHDAO lgdHDAO = LgdHDAO.getFromApplicationContext(ctx);
	private QuaValueDAO quaValueDAO = QuaValueDAO.getFromApplicationContext(ctx);
	private AdjValueDAO adjValueDAO = AdjValueDAO.getFromApplicationContext(ctx);
	private RatioValueDAO ratioValueDAO = RatioValueDAO.getFromApplicationContext(ctx);
	private ModelInfoDAO modelInfoDAO = ModelInfoDAO.getFromApplicationContext(ctx);
	private DebtCollateralDAO debtCollateralDAO = DebtCollateralDAO.getFromApplicationContext(ctx);
	private DebtInfoDAO debtInfoDAO = DebtInfoDAO.getFromApplicationContext(ctx);
	
	@Resource
	private SystemService systemService;
	
	//按客户查找其历史评级信息
	@SuppressWarnings("unchecked")
	public List<PdH> findHistoryRatingPdH(String custId) {
		List<PdH> list = new ArrayList<PdH>();
		//已认定的按时间降序排列的评级列表
		List<PdH> sortedConfirmedList;
		
		//首先查找最新的评级，如果是非认定，则加入list中,否则不加入
		List<PdH> allList = pdhDAO.findAllPDByCustId(custId);
		PdH lastPd = new PdH();
		if(allList!=null && allList.size() > 0){
			lastPd = allList.get(allList.size()-1);
		}
		if(allList!=null && allList.size() >0 && lastPd.getPhaseStat() != null && !lastPd.getPhaseStat().equals(PdH.CONFIRM_FINISH)&& !lastPd.getPhaseStat().equals(PdH.INVALIDATE)){
			//	置为其他非认定&有效状态的结果
				PdH p = allList.get(allList.size()-1);
				p.setConfirmPdlevel(getLevel(p));
				p.setConfirmPdvalue(getValue(p));
				list.add(p);
			}
		
		//其次查找所有已认定的历史评级并按时间降序排列
		sortedConfirmedList = pdhDAO.findSortedConfirmedList(custId);
		
		if(sortedConfirmedList!=null && sortedConfirmedList.size()>0)
			list.addAll(sortedConfirmedList);
		
		return list;
	}
	
	private Double getValue(PdH p) {
		if(p.getPhaseStat().equals("02"))
			return p.getFirstPdvalue();
		else if(p.getPhaseStat().equals("03"))
			return p.getSecondPdvalue();
		else if(p.getPhaseStat().equals("04"))
			return p.getFirstPdvalue();
		else
			return p.getConfirmPdvalue();
	}

	private String getLevel(PdH p) {
		if(p.getPhaseStat().equals("02"))
			return p.getFirstPdlevel();
		else if(p.getPhaseStat().equals("03"))
			return p.getSecondPdlevel();
		else if(p.getPhaseStat().equals("04"))
			return p.getFirstPdlevel();
		else if(p.getPhaseStat().equals("05"))
			return p.getConfirmPdlevel();
		else
			return p.getSystemPdlevel();
	}

	//列出每个客户的最新评级信息，按照评级状态和时间排序
	public List<PdH> listCustSortedRating() {
		return pdhDAO.listCustSortedRating();
	}
	//列出每个客户的最新评级信息，按照评级状态和时间排序
	public List<PdH> listCustSortedRatingByUser(String userId, String orgId, boolean isRetail) {
		if(userId == null || "".equals(userId) || orgId == null || "".equals(orgId))return listCustSortedRating();
		
		List<String> subOrgIdList = new ArrayList<String>();
		subOrgIdList.addAll(orgMap.get(orgId));
		List<RoleInfo> roleList = systemService.findRoleByUserId(userId);
		String accessURL = RoleRightInit.getInstance().getRightMap().get(roleList.get(0).getRoleId()).get("accessURL");
		
		//不同权限可见性不同：（当前：除发起，其他权限均可见本部门的其他用户的客户）
		//权限--评级发起
		if(accessURL.contains("CustomerRating_FirstPD")){
		}
		//权限--评级复评
		else if(accessURL.contains("CustomerRating_FirstVerifyPD")){
			subOrgIdList.add(orgId);
		}
		//权限--评级审核
		else if(accessURL.contains("CustomerRating_SecondPD")){
			subOrgIdList.add(orgId);
		}
		//权限--评级认定
		else if(accessURL.contains("CustomerRating_ConfirmPD")){
			subOrgIdList.add(orgId);
		}
		return pdhDAO.listCustSortedRatingByUser(userId, subOrgIdList, isRetail);
	}
	
	
	//获得某一个客户的最新评级,如果没有，则new一个新对象，将其状态位置为未评级
	public PdH getNewestPDByCustId(String custId) {
		
		return null;
	}

	public List<PdH> findReportHistoryRatingPdH(String ratingCustId) {
		List<PdH> list = new ArrayList<PdH>();
		//已认定的按时间降序排列的评级列表
		List<PdH> sortedConfirmedList;
		
		//首先查找最新的评级，如果是非认定，则加入list中,否则不加入
//		List<PdH> allList = pdhDAO.findAllPDByCustId(ratingCustId);
//		if(allList!=null && allList.size() >0 && !allList.get(allList.size()-1).getPhaseStat().equals(PdH.CONFIRM_FINISH)){
//			//	置为其他非认定状态的结果
//				PdH p = allList.get(allList.size()-1);
//				p.setConfirmPdlevel(getLevel(p));
//				p.setConfirmPdvalue(getValue(p));
//				list.add(p);
//			}
		
		//其次查找所有已认定的历史评级并按时间降序排列
		sortedConfirmedList = pdhDAO.findSortedConfirmedList(ratingCustId);
		
		if(sortedConfirmedList!=null && sortedConfirmedList.size()>0)
			list.addAll(sortedConfirmedList);
		
		return list;
	}

	public PdH findPDById(String serialNo) {
		return pdhDAO.findById(serialNo);
	}

	public void insertLGD(LgdH lgdH) {
		lgdHDAO.save(lgdH);
	}

	public void insertPdH(PdH pd) {
		pdhDAO.save(pd);
	}

	public QuaValue findQuaValueBySerialNoModelIdAndItemNo(String serialNo, String modelId, String itemNo) {
		return quaValueDAO.findQuaValueBySerialNoModelIdAndItemNo(serialNo, modelId, itemNo);
	}

	public void insertQuaValueList(List<QuaValue> list) {
		quaValueDAO.insertQuaValueList(list);
	}

	public QuaValue findQuaValueById(QuaValueId id) {
		return quaValueDAO.findById(id);
	}

	public List<QuaValue> findQuaValueBySerialNoAndModelId(String serialNo,String modelId) {
		return quaValueDAO.findQuaValueBySerialNoAndModelId(serialNo,modelId);
	}

	public void deleteQuaValue(QuaValue qv) {
		quaValueDAO.delete(qv);
	}

	public List<AdjValue> findAdjValueBySerialNoAndModelId(String serialNo,String modelId) {
		return adjValueDAO.findAdjValueBySerialNoAndModelId(serialNo,modelId);
	}

	public AdjValue findAdjValueBySerialNoModelIdAndItemNo(String serialNo,String modelId, String itemNo) {
		return adjValueDAO.findAdjValueBySerialNoModelIdAndItemNo(serialNo,modelId,itemNo);
	}

	public void insertAdjValueList(List<AdjValue> list) {
		adjValueDAO.insertAdjValueList(list);
	}

	public RatioValue findRatioValueByRatioValueId(com.moody.hibernate.domain.RatioValueId id){
		return ratioValueDAO.findById(id);
	}
	@SuppressWarnings("unchecked")
	public List<RatioValue> findRatioValueBySerialNoAndModelId(String serialNo,String modelId) {
		List<RatioValue> ratioList = ratioValueDAO.findRatioValueBySerialNoAndModelId(serialNo,modelId);
		if(ratioList.size() > 0 && ratioList.get(0).getId().getReportItemNo().length() >= 12) {//定量为手选的情况：
			for(RatioValue ratio :ratioList){
				List<ModelInfo> list = modelInfoDAO.findByItemNo(ratio.getId().getReportItemNo());
				ModelInfo model = new ModelInfo();
				for( ModelInfo m : list){
					if(m.getItemValue().equals(ratio.getItemValue()))
						model = m;
				}
				ratio.setDescribe(model.getDescribe2());
				ratio.setItemDescription(model.getItemDescribe());
			}
			
		}
		return ratioList;
	}

	public void insertRatioValueList(List<RatioValue> ratioValueList) {
		ratioValueDAO.insertRatioValueList(ratioValueList);
	}

	public void updatePdH(PdH ratingPD) {
		pdhDAO.update(ratingPD);
	}

	public PdH findRecentPDByCustId(String custId) {
		return pdhDAO.findNewestPDByCustId(custId);
	}

	public List<PdH> listCustSortedRatingByConfirmDate() {
		return pdhDAO.listCustSortedRatingByConfirmDate();
	}
	
	public void invalidatePdH(String custId){
		pdhDAO.invalidatePdH(custId);
	}
	
	public int getConfirmedOrderByConfirmDate(String serialNo,String confirmDate){
		int num = 0;
		List<PdH> list = pdhDAO.findByConfirmDate(confirmDate);
		if(list == null) return 0;
		for(PdH pdh :list){
			if(pdh.getPhaseStat().equals(PdH.CONFIRM_FINISH) && serialNo.compareTo(pdh.getSerialNo()) >= 0)num++;
		}
		return num;
	}
	
	public int getIndConfirmedOrderBySecondDate(String serialNo,String secondDate){
		int num = 0;
		List<PdH> list = pdhDAO.findBySecondDate(secondDate);
		if(list == null) return 0;
		for(PdH pdh :list){
			if( (pdh.getConfirmDate() == null || "".equals(pdh.getConfirmDate())) && pdh.getPhaseStat().equals(PdH.CONFIRM_FINISH) && serialNo.compareTo(pdh.getSerialNo()) >= 0)num++;
		}
		return num;
	}
	
	public double getShare(String debtNo, double exposureValueTemp, String collateralId){
		List<DebtCollateral> dcList = debtCollateralDAO.findByCollateralId(collateralId);
		double sum = 0.0;
		for(DebtCollateral dc : dcList){
			DebtInfo debt = debtInfoDAO.findById(dc.getId().getDebtNo());
			if(!dc.getId().getDebtNo().equals(debtNo))sum += debt.getDebtBalance();
		}
		return exposureValueTemp/ (sum + exposureValueTemp);
		
	}
}
